﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Serialization;

namespace HomeWork5_1
{
    [Serializable]
    public class Order
    {
        public OrderDetails[] ord;//订单
        public int sumMount = 0;

        public Order()
        {
        }

        public Order(OrderDetails[] ord)
        {
            this.ord = ord;
            foreach (OrderDetails o in ord)
            {
                sumMount += o.amount;
            }
        }

        public override bool Equals(object obj)
        {
            Order tar = obj as Order;
            if (tar == null)
                return false;
            for (int i = 0; i < ord.Length; i++)
            {
                if (!tar.ord[i].Equals(ord[i]))
                    return false;
            }
            return true;
        }

        public override int GetHashCode()
        {
            return -785982304 + EqualityComparer<OrderDetails[]>.Default.GetHashCode(ord);
        }

        public override string ToString()
        {
            string s = "";
            foreach (OrderDetails o in ord)
            {
                s += o.ToString() + "\n";
            }
            return "Order的订单详情：\n" + s;
        }
    }
    [Serializable]
    public class Client
    {
        public string name;

        public Client()
        {
        }

        public Client(string name)
        {
            this.name = name;
        }

        public override bool Equals(object obj)
        {
            return obj is Client client &&
                   name == client.name;
        }

        public override int GetHashCode()
        {
            return 363513814 + EqualityComparer<string>.Default.GetHashCode(name);
        }

        public override string ToString()
        {
            return "客户名字：" + name + "，";
        }
    }
    [Serializable]
    public class Commodity//货物
    {
        public string name;
        public int num;//数量

        public Commodity()
        {
        }

        public Commodity(string name, int num)
        {
            this.name = name;
            this.num = num;
        }

        public override bool Equals(object obj)
        {
            return obj is Commodity commodity &&
                   name == commodity.name &&
                   num == commodity.num;
        }

        public override int GetHashCode()
        {
            int hashCode = 605889929;
            hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(name);
            hashCode = hashCode * -1521134295 + num.GetHashCode();
            return hashCode;
        }

        public override string ToString()
        {
            return "货物名称：" + name + "货物数量：" + num + "，";
        }
    }
    [Serializable]
    public class OrderDetails
    {
        public int id;//订单号
        public Commodity commodity;//商品名称
        public Client client;//客户
        public int amount;//订单金额

        public OrderDetails()
        {
        }

        public OrderDetails(int id, Commodity commodity, Client client, int amount)
        {
            this.id = id;
            this.commodity = commodity;
            this.client = client;
            this.amount = amount;
        }

        public override bool Equals(object obj)
        {
            return obj is OrderDetails details &&
                   id == details.id &&
                   commodity.Equals(details.commodity) &&
                   client.Equals(details.client) &&
                   amount == details.amount;
        }

        public override int GetHashCode()
        {
            int hashCode = -1951372695;
            hashCode = hashCode * -1521134295 + id.GetHashCode();
            hashCode = hashCode * -1521134295 + EqualityComparer<Commodity>.Default.GetHashCode(commodity);
            hashCode = hashCode * -1521134295 + EqualityComparer<Client>.Default.GetHashCode(client);
            hashCode = hashCode * -1521134295 + amount.GetHashCode();
            return hashCode;
        }

        public override string ToString()
        {
            return "订单号：" + id + commodity.ToString() + client.ToString() + "订单金额：" + amount;
        }
    }
    [Serializable]
    public class OrderService
    {
        public List<Order> list = new List<Order>();
        public OrderService()
        {
        }
        //按订单号排序
        public void sortById()
        {
            list.Sort((p1, p2) => p1.ord[0].id - p2.ord[0].id);//按照每个订单中的第一个订单号排序
        }

        public void init()
        {
            Commodity com = new Commodity("phone", 11);
            Client client = new Client("Jack");
            OrderDetails[] order = { new OrderDetails(0, com, client, 20) };
            Order ord = new Order(order);
            Console.WriteLine("添加订单1：" + ord.ToString());
            list.Add(ord);

            Commodity com2 = new Commodity("dress", 2);
            Client client2 = new Client("Anger");
            OrderDetails[] order2 = { new OrderDetails(0, com2, client2, 33), new OrderDetails(1, new Commodity("pants", 8), new Client("Jane"), 11) };
            Order ord2 = new Order(order2);
            Console.WriteLine("添加订单2：" + ord2.ToString());
            list.Add(ord2);
        }
        public bool addOrder(int id, string comName, int comNum, string clientName, int amount)
        {
            try
            {
                Commodity com = new Commodity(comName, comNum);
                Client client = new Client(clientName);
                OrderDetails[] order = { new OrderDetails(id, com, client, amount) };
                Order ord = new Order(order);
                foreach (Order lo in list)
                {
                    if (ord.Equals(lo))
                        return false;//有相同订单不允许添加
                }

                list.Add(ord);
                return true;
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                return false;
            }
        }
        public bool deleteOrder(int id)
        {//按订单号查询并删除
            try
            {
                foreach (Order l in list)
                {
                    var q = from o in l.ord
                            where o.id == id
                            select o;
                    if (q != null)
                    {
                        list.Remove(l);
                        break;
                    }
                }
                /*                var query = from l in list
                                            where l.ord.id == id
                                            select l;
                                foreach (var x in query)
                                {
                                    list.Remove(x);
                                }*/
                return true;
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                return false;
            }
        }
        public bool changeOrder(int id, string comName, int comNum, string clientName, int amount)
        {
            try
            {
                IEnumerable<OrderDetails> q;
                foreach (Order l in list)
                {
                    q = from p in l.ord
                            where p.id == id
                            select p;
                    if (q.Any())
                    {
                        list.Remove(l);
                        OrderDetails[] toInsert = { new OrderDetails(id, new Commodity(comName, comNum), new Client(clientName), amount) };
                        Order o = new Order(toInsert);
                        list.Add(o);
                        break;//找到一个就修改了
                    }
                }
                return true;
            }catch(Exception e)
            {
                return false;
            }
            /*            var query = from l in list
                                    where l.ord.id == id
                                    orderby l.ord.amount
                                    select l;
                        OrderDetails[] toInsert = {new OrderDetails(id, new Commodity(comName, comNum), new Client(clientName), amount)};
                        Order o = new Order(toInsert);
                        foreach(var x in query)
                        {
                            list.Remove(x);
                        }
                        list.Add(o);*/
        }
        public bool searchById(int id)
        {
            try
            {
                Console.WriteLine("搜索条件为：订单号" + id + "，查询得，");
                var query = from l in list
                            where ((from o in l.ord where o.id == id select o).Any())//列表清单中有匹配项
                            orderby l.sumMount
                            select l;
                foreach (var x in query)
                {
                    Console.WriteLine(x.ToString());
                }
                return true;
            }catch(Exception e)
            {
                return false;
            }
        }
        public bool searchByCommodity(string comName)
        {
            try
            {
                var query = from l in list
                            where (from o in l.ord where o.commodity.name == comName select o).Any()
                            orderby l.sumMount
                            select l;
                foreach (var x in query)
                {
                    Console.WriteLine(x.ToString());
                }
                return true;
            }catch(Exception e)
            {
                return false;
            }
        }
        public bool searchByClient(string clientName)
        {
            try
            {
                Console.WriteLine("搜索条件为：客户名" + clientName + "，查询得，");
                var query = from l in list
                            where (from o in l.ord where o.client.name == clientName select o).Any()
                            orderby l.sumMount
                            select l;
                foreach (var x in query)
                {
                    Console.WriteLine(x.ToString());
                }
                return true;
            }catch(Exception e)
            {
                return false;
            }
        }
        public bool searchByAmount(int amount)
        {
            try
            {
                var query = from l in list
                            where (from o in l.ord where o.amount == amount select o).Any()
                            orderby l.sumMount
                            select l;
                foreach (var x in query)
                {
                    Console.WriteLine(x.ToString());
                }
                return true;
            }catch(Exception e)
            {
                return false;
            }
        }
        public void Export()
        {
            XmlSerializer xmlserializer = new XmlSerializer(typeof(List<Order>));
            using (FileStream fs = new FileStream("订单.xml", FileMode.Create))
            {
                xmlserializer.Serialize(fs, list);
                Console.WriteLine("\nSerialized successful!");
            }
        }
        public bool Import(string src)
        {
            try
            {
                XmlSerializer xmlserializer = new XmlSerializer(typeof(Order[]));
                using (FileStream fs = new FileStream(src, FileMode.Open))
                {
                    Order[] l2 = (Order[])xmlserializer.Deserialize(fs);
                    Array.ForEach(l2, p => { Console.WriteLine(p.ToString()); list.Add(p); });

                }
                return true;
            }catch(Exception e)
            {
                return false;
            }
        }
    }
    internal class Program
    {
        static void Main(string[] args)
        {
            OrderService server = new OrderService();
            server.init();
            //server.searchByClient("Jack");
            //server.Export();
            //server.Import("订单.xml");
            Console.Write(server.changeOrder(1, "a", 10, "s", 1));
            Console.ReadLine();
        }
    }
}
